﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace theguineasyndrome
{
    public class PaintWeapon : Weapon
    {
        private Texture2D[] dropTextures;
        private Texture2D[] flakeTextures;
        private Texture2D[] splashTextures;
        private List<PaintDrop> drops;
        private Random random;

        public PaintWeapon(Texture2D[] flakeTextures, Texture2D[] dropTextures, Texture2D[] splashTexture)
        {
            this.flakeTextures = flakeTextures;
            this.dropTextures = dropTextures;
            this.splashTextures = splashTexture;
            drops = new List<PaintDrop>();
            random = new Random();
        }

        public override Vector2 firePrimary(int time, Vector2 position, Vector2 speed)
        {
            speed *= 17;
            speed.X += ((float)random.NextDouble() - 0.5f) * 1.5f;
            speed.Y += ((float)random.NextDouble() - 0.5f) * 1.5f;

            drops.Add(new PaintDrop(level, getRandomFlakeTexture(), position, speed, PaintDrop.LIFE_TIME - (float)random.NextDouble() / 2, time));
            return new Vector2();
        }

        public override Vector2 fireSecondary(int time, Vector2 position, Vector2 speed)
        {
            return new Vector2();
        }

        public override float getPrimaryPeriod()
        {
            return 10;
        }

        public override float getSecondaryPeriod()
        {
            return 10;
        }

        public override bool primaryRequiresJustClicked()
        {
            return false;
        }

        public override bool secondaryRequiresJustClicked()
        {
            return false;
        }

        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            int time = (int)gameTime.TotalGameTime.TotalMilliseconds;
            List<PaintDrop> newDrops = new List<PaintDrop>();

            for (int i = drops.Count - 1; i >= 0; i--)
            {
                LiquidDrop drop = drops[i];
                drop.Update(gameTime);
                if (drop.isDead())
                {
                    ObstacleElement killingObstacle = drop.getKillingObstacle();
                    if (killingObstacle != null && killingObstacle.getSide(drop.Position, drop.Speed) == LevelElement.Side.TOP)
                    {
                        Vector2 splashPosition = new Vector2(drop.X, 0);

                        Texture2D splashTexture = getRandomSplashTexture();

                        if (splashPosition.X < killingObstacle.Left + splashTexture.Width / 2)
                            splashPosition.X = killingObstacle.Left + splashTexture.Width / 2;

                        else if (splashPosition.X > killingObstacle.Right - splashTexture.Width / 2)
                            splashPosition.X = killingObstacle.Right - splashTexture.Width / 2;

                        splashPosition.Y = (float)(killingObstacle.CollisionTop + (random.NextDouble() - 0.5) * (ObstacleElement.DEPTH - splashTexture.Height));

                        killingObstacle.addTopSplash(new SpeedSplash(splashTexture, splashPosition));
                    }

                    float lifeTime = drop.getLifeTime() - 0.5f - (float)random.NextDouble() / 2;
                    if (lifeTime > 0)
                    {
                        Vector2 speed = drop.NextDropSpeed;

                        int numDrops = random.Next(2, 5);
                        for (int j = 0; j < numDrops; j++)
                        {
                            speed.X = speed.X + (float)(random.NextDouble() - 0.5) * lifeTime * 7;
                            speed.Y = speed.Y + (float)(random.NextDouble() - 0.5) * lifeTime * 7;
                            speed *= 0.6f;
                            newDrops.Add(new PaintDrop(level, getRandomDropTexture(), drop.Position, speed, lifeTime, time));
                        }
                    }

                    drops.RemoveAt(i);
                }
            }

            foreach (PaintDrop newDrop in newDrops)
                drops.Add(newDrop);
        }

        public override void queueDrawing(Camera camera)
        {
            foreach (PaintDrop drop in drops)
                drop.queueDrawing(camera);
        }

        private Texture2D getRandomFlakeTexture()
        {
            return flakeTextures[random.Next(flakeTextures.Length)];
        }

        private Texture2D getRandomDropTexture()
        {
            return dropTextures[random.Next(dropTextures.Length)];
        }

        private Texture2D getRandomSplashTexture()
        {
            return splashTextures[random.Next(splashTextures.Length)];
        }

        public override void clear()
        {
            drops.Clear();
        }
    }
}
